package com.player.rest.resource;

import java.net.URI;
import java.security.Principal;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.Status;

import org.json.JSONException;

import com.player.dao.DAOLocator;
import com.player.entity.Game;
import com.player.entity.Player;
import com.player.rest.exception.FaultInfo;
import com.player.rest.exception.ServiceErrorCode;
import com.player.rest.exception.ServiceException;
import com.player.rest.util.ResponseConverter;
import com.player.rest.util.ValidationResult;

@Path("games")
public class GameResource {

	public static final String FORM_PARAM_CREATOR = "creatorId";
	public static final String FORM_PARAM_OPPONENT = "opponentId";

	@Context
	UriInfo uriInfo;

	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response createNewGame(@FormParam(FORM_PARAM_CREATOR) Long creatorId,
			@FormParam(FORM_PARAM_OPPONENT) Long opponentId) throws JSONException {

		Map<Long, Player> playersById = DAOLocator.getPlayerDAO().get(creatorId, opponentId);
		if (playersById == null) {
			ValidationResult result = new ValidationResult();
			result.addMessage("error",
					"Game could not be created because either creator and/or opponent was not found! (creatorId="
							+ creatorId + ", opponentId=" + opponentId + ")");
			return Response.status(Status.NOT_FOUND).entity(ResponseConverter.buildErrorJSON(result).toString())
					.build();
		}

		Game newGame = DAOLocator.getGameDAO().createOrReplace(creatorId, opponentId);
		return Response.created(getUri(newGame)).build();
	}

	@POST
	@Path("{gameId}/result")
	@Produces(MediaType.APPLICATION_JSON)
	public Response createResult(@PathParam("gameId") Long gameId, @FormParam(FORM_PARAM_CREATOR) Long creatorId,
			@FormParam("setsWonByCreator") int setsWonByCreator, @FormParam("setsWonByOpponent") int setsWonByOpponent,
			@Context SecurityContext sc) {

		Principal principal = sc.getUserPrincipal();
		if (principal == null) {
			// FIXME impl return response forbidden (do this in other resources... use ResourceFilter? where to do this?
		} else {
			// FIXME impl if user not exists OR user isnot creator => return response forbidden
		}

		Game game = DAOLocator.getGameDAO().get(gameId);
		if (game == null) {
			FaultInfo fault = new FaultInfo(ServiceErrorCode.RESOURCE_NOT_FOUND, "Game with id=" + gameId
					+ " not found.");
			throw new ServiceException(Status.NOT_FOUND, fault);
		}

		// store the result (not yet approved by opponent - therefore no points etc. calculated)
		// FIXME impl gameDAO.createResult(gameKey, setsWonByCreator, setsWonByOpponent);

		return null;
	}

	@POST
	@Path("{gameId}/result/confirm")
	@Produces(MediaType.APPLICATION_JSON)
	public Response confirmResult(@PathParam("gameId") Long gameId, @Context SecurityContext sc) {
		// FIXME auth
		return Response.status(Status.OK).build();
	}

	private URI getUri(Game game) {
		return uriInfo.getAbsolutePathBuilder().path(game.getId().toString()).build();
	}
}
